//! 数据接收器

use crate::consts::*;
use crate::link::frame::*;
use heapless::Vec;

/// 接收器状态
enum Status {
    Lead(u8),
    Start,
    Length1,
    Length2,
    End,
}

/// 接收器
pub struct Recver {
    /// 已处理的数据
    buf: Vec<u8, FrameLen>,
    /// 待处理的数据
    pend: Vec<u8, FrameLen>,
    /// 负载长度
    load_len: usize,
    /// 接收状态
    status: Status,
}
impl Recver {
    /// 创建一个空的接收器
    pub fn new() -> Self {
        Recver {
            buf: Vec::new(),
            pend: Vec::new(),
            load_len: 0,
            status: Status::Lead(0),
        }
    }
    /// 接收器是否为空
    pub fn is_empty(&self) -> bool {
        self.pend.is_empty() && self.buf.is_empty()
    }
    /// 清空接收器中处理完的数据
    fn clean(&mut self) {
        self.buf.clear();
        self.status = Status::Lead(0);
    }
    /// 处理一个字节
    fn recv_one(&mut self, res: u8) -> bool {
        match self.status {
            Status::Lead(mut count) => {
                if res == CHAR_LEAD {
                    count += 1;
                    if count >= 3 {
                        self.status = Status::Start;
                    } else {
                        self.status = Status::Lead(count);
                    }
                } else {
                    self.clean();
                }
            }
            Status::Start => {
                if res == CHAR_LEAD {
                } else if res == CHAR_START {
                    self.buf.push(res).unwrap();
                    self.status = Status::Length1;
                } else {
                    self.clean();
                }
            }
            Status::Length1 => {
                self.buf.push(res).unwrap();
                self.status = Status::Length2;
            }
            Status::Length2 => {
                self.buf.push(res).unwrap();
                self.load_len = (self.buf[Field::Length as usize] as usize) << 8
                    | self.buf[Field::Length as usize + 1] as usize;
                if self.load_len > LOAD_LEN {
                    self.clean();
                } else {
                    self.status = Status::End;
                }
            }
            Status::End => {
                if self.buf.len() < self.load_len + MIN_LEN - 1 {
                    self.buf.push(res).unwrap();
                } else {
                    if res == CHAR_END {
                        self.buf.push(res).unwrap();
                        return true;
                    } else {
                        self.clean();
                        self.recv_one(res);
                    }
                }
            }
        }
        return false;
    }
    /// 接收数据并找出一个数据帧，复制给load负载数据，返回负载长度
    pub fn recv(&mut self, buf: &[u8], load: &mut [u8]) -> usize {
        if buf.len() > 0 {
            // 追加到待处理数据中
            self.pend.extend_from_slice(buf).unwrap();
        }
        for i in 0..self.pend.len() {
            let res = self.pend[i];
            let finish = self.recv_one(res);
            if finish {
                let load_len = frame2load(&self.buf, load);
                self.clean();
                if load_len > 0 {
                    self.pend = Vec::<u8, FrameLen>::from_slice(&self.pend[i + 1..]).unwrap();
                    return load_len;
                }
            }
        }
        self.pend.clear();
        return 0;
    }
}
